package com.ybkj.daijia.api.member.v1;

import com.ybkj.daijia.Setting;
import com.ybkj.daijia.serverUtils.SettingUtils;
import com.ybkj.daijia.api.member.ErrorConstant;
import com.ybkj.daijia.api.member.alipay.config.AlipayConfig;
import com.ybkj.daijia.api.member.alipay.util.AlipayNotify;
import com.ybkj.daijia.api.member.transport.ResultTransport;
import com.ybkj.daijia.api.weixin.tenpayv3.TenpayUtil;
import com.ybkj.daijia.server.mc.Passenger;
import com.ybkj.daijia.server.model.PayRecord;
import com.ybkj.daijia.server.model.PayRecord.PayRecordType;
import com.ybkj.daijia.server.service.MemberAccountService;
import com.ybkj.daijia.server.service.MemberService;
import com.ybkj.daijia.server.service.PayRecordService;
import java.io.UnsupportedEncodingException;
import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

/**
 * 支付相关
 *
 * @author mqs
 */
@Controller("MemberPayController")
@RequestMapping(value = "member/api/rest/v1/pay")
public class PayController {

    private static final Logger logger = LoggerFactory.getLogger(PayController.class);

    @Autowired
    private MemberAccountService memberAccountService;

    @Autowired
    private PayRecordService payRecordService;

    @Autowired
    private MemberService memberService;

    @Autowired
    private SettingUtils settingUtils;


    @RequestMapping(value = "alipay/prepay")
    public @ResponseBody
    ResultTransport alipayPrepay(HttpServletResponse response, HttpServletRequest request,
        String phone, String deviceType, BigDecimal money) {

        logger.debug("recv phone:{},deviceType:{},money:{}", phone, deviceType, money);

        if (StringUtils.isBlank(phone) || StringUtils.isBlank(deviceType) || null == money) {
            return ResultTransport.getErrorBy(ErrorConstant.PARAM_ERROR);
        }

        Passenger passenger = memberService.findOnePassengerByPhone(phone);
        if (null == passenger) {
            return ResultTransport.getErrorBy(ErrorConstant.MEMBER_NOT_EXISTS_ERROR);
        }

        try {

            Date now = new Date();
            SimpleDateFormat outFormat = new SimpleDateFormat("yyyyMMddHHmmss");
            String currTime = outFormat.format(now);
            String strTime = currTime.substring(8, currTime.length());
            String strRandom = TenpayUtil.buildRandom(8) + "";
            String tradeNO = strTime + strRandom;

            PayRecord payRecord = new PayRecord();
            payRecord.setAmount(money);
            payRecord.setDeviceType(deviceType);
            payRecord.setMemberId(passenger.getId());
            payRecord.setPhone(phone);
            payRecord.setTradeNO(tradeNO);
            payRecord.setPayRecordType(PayRecordType.alipay);

            payRecordService.inertRecord(payRecord);

            ResultTransport instance = ResultTransport.getErrorBy(ErrorConstant.SUCCESS);

            Setting setting = settingUtils.get();

            Map<String, Object> map = new HashMap<String, Object>();
            map.put("PartnerID", setting.getAlipayPartnerID());
            map.put("SellerID", setting.getAlipaySellerID());
            map.put("PartnerPrivKey", setting.getAlipayPartnerPrivKey());
//			map.put("PartnerPublicKey", setting.getAlipayPartnerPublicKey());
            map.put("PartnerPublicKey", AlipayConfig.ali_public_key);
            map.put("tradeNO", payRecord.getTradeNO());
            map.put("productName", "会员充值");
            map.put("productDescription", "会员充值");
//			map.put("amount", 0.01);
            map.put("amount", payRecord.getAmount());
            map.put("notifyURL", setting.getWebUrl() + "/member/api/rest/v1/pay/alipay/notify");

            instance.setData(map);

            return instance;

        } catch (Exception e) {
            logger.error("api v1 pay alipay/prepay error: {}", e);
            return ResultTransport.getErrorBy(ErrorConstant.SERVER_ERROR);
        }
    }


    @RequestMapping(value = "alipay/notify")
    public synchronized @ResponseBody
    String alipayNotify(HttpServletResponse response, HttpServletRequest request)
        throws UnsupportedEncodingException {
        logger.debug("alipay/notify---------------");

        Setting setting = settingUtils.get();

        //获取支付宝POST过来反馈信息
        Map<String, String> params = new HashMap<String, String>();
        Map requestParams = request.getParameterMap();
        for (Iterator iter = requestParams.keySet().iterator(); iter.hasNext(); ) {
            String name = (String) iter.next();
            String[] values = (String[]) requestParams.get(name);
            String valueStr = "";
            for (int i = 0; i < values.length; i++) {
                valueStr = (i == values.length - 1) ? valueStr + values[i]
                    : valueStr + values[i] + ",";
            }
            //乱码解决，这段代码在出现乱码时使用。如果mysign和sign不相等也可以使用这段代码转化
            //valueStr = new String(valueStr.getBytes("ISO-8859-1"), "gbk");
            params.put(name, valueStr);
        }

        //获取支付宝的通知返回参数，可参考技术文档中页面跳转同步通知参数列表(以下仅供参考)//

        //商户订单号
        String out_trade_no = new String(
            request.getParameter("out_trade_no").getBytes("ISO-8859-1"), "UTF-8");

        //支付宝交易号
        String trade_no = new String(request.getParameter("trade_no").getBytes("ISO-8859-1"),
            "UTF-8");

        //交易状态
        String trade_status = new String(
            request.getParameter("trade_status").getBytes("ISO-8859-1"), "UTF-8");

        //获取支付宝的通知返回参数，可参考技术文档中页面跳转同步通知参数列表(以上仅供参考)//

        logger.debug("商户订单号：" + out_trade_no);
        logger.debug("交易号：" + trade_no);
        logger.debug("交易状态：" + trade_status);

        if (AlipayNotify.verify(params, setting)) {//验证成功
            //请在这里加上商户的业务逻辑程序代码

            if (trade_status.equals("TRADE_FINISHED")) {
                //判断该笔订单是否在商户网站中已经做过处理
                //如果没有做过处理，根据订单号（out_trade_no）在商户网站的订单系统中查到该笔订单的详细，并执行商户的业务程序
                //如果有做过处理，不执行商户的业务程序

                //注意：
                //该种交易状态只在两种情况下出现
                //1、开通了普通即时到账，买家付款成功后。
                //2、开通了高级即时到账，从该笔交易成功时间算起，过了签约时的可退款时限（如：三个月以内可退款、一年以内可退款等）后。
                PayRecord payRecord = payRecordService.findByTradeNO(out_trade_no);
                if (null != payRecord && !payRecord.isTreatment()) {

                    try {
                        memberService.cashRecharge(payRecord, trade_no);
                        logger.debug("success-----------------");
                        return "success";
                    } catch (Exception e) {
                        logger.debug("fail：" + e.getMessage());
                    }

                } else {
                    logger.debug("订单：" + out_trade_no + "不存在或已完成");
                }


            } else if (trade_status.equals("TRADE_SUCCESS")) {
                //判断该笔订单是否在商户网站中已经做过处理
                //如果没有做过处理，根据订单号（out_trade_no）在商户网站的订单系统中查到该笔订单的详细，并执行商户的业务程序
                //如果有做过处理，不执行商户的业务程序

                //注意：
                //该种交易状态只在一种情况下出现——开通了高级即时到账，买家付款成功后。
                PayRecord payRecord = payRecordService.findByTradeNO(out_trade_no);
                if (null != payRecord && !payRecord.isTreatment()) {
                    try {
                        memberService.cashRecharge(payRecord, trade_no);
                        logger.debug("success-----------------");
                        return "success";
                    } catch (Exception e) {
                        logger.debug("fail：" + e.getMessage());
                    }
                } else {
                    logger.debug("订单：" + out_trade_no + "不存在或已完成");
                }
            }

            logger.debug("fail-----------------");
            return "fail";

        } else {
            logger.debug("验证失败-----------------");
            return "fail";
        }
    }

}
